package com.sunflower.common.core.utils;

import cn.hutool.core.util.ObjectUtil;
import com.sunflower.common.core.domain.model.SimpleToTreeInfo;
import com.sunflower.common.core.domain.model.ToTreeInfo;
import com.sunflower.common.core.domain.model.Tree;
import com.sunflower.common.core.interceptor.SFunction;

import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author: SunLuQuan
 * @Date: 2024年04月01日 16:33
 * @Description: TreeUtils
 */
public class TreeUtils {

    public static <T> ToTreeInfo<T> buildToTreeInfo(SFunction<T, Serializable> parentId, SFunction<T, Serializable> id) {
        return buildToTreeInfo(parentId, id, null);
    }

    public static <T> ToTreeInfo<T> buildToTreeInfo(SFunction<T, Serializable> parentId, SFunction<T, Serializable> id, SFunction<T, Serializable> name) {

        return new SimpleToTreeInfo<>(parentId, id, name);
    }

    /**
     * 将list转成tree
     *
     * @param list       泛型集合
     * @param toTreeInfo 使得普通对象转Tree对象辅助信息存储接口
     * @param <T>        泛型
     * @return Tree对象集合
     */
    public static <T> List<Tree<T>> toTree(List<T> list, ToTreeInfo<T> toTreeInfo) {
        List<Tree<T>> rootTreeList = list.stream().filter(toTreeInfo::condition)
            .map(item -> toTreeInfo.toTree(null, item))
            .collect(Collectors.toList());
        return rootTreeList;
    }

    private <T> List<Tree<T>> getTreeList_(Tree<T> parent, List<T> list, ToTreeInfo<T> toTreeInfo) {
        List<Tree<T>> rootList = list.stream()
            .filter(item -> ObjectUtil.equals(toTreeInfo.parentId().apply(item), toTreeInfo.id().apply(parent.getData())))
            .map(item -> toTreeInfo.toTree(parent, item)).collect(Collectors.toList());
        rootList.forEach(item ->
            item.setChild(getTreeList_(item, list, toTreeInfo))
        );
        return rootList;
    }
}
